home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / files.swg / 0104_Managing the .INI type datafile.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-05-30  |  6.0 KB  |  317 lines

  1. {.$DEFINE SECURE}
  2.  
  3. unit DataFile; {- managing the .ini - type datafile}
  4.  
  5. interface
  6.  
  7. type
  8.   DataStr = String[80];
  9.  
  10.   PDataFile = ^TDataFile;
  11.   TDataFile = object
  12.     F, FTmp  : Text;
  13.     FileName : String;
  14.     EndTopic : Boolean;
  15.     CurTopic : DataStr;
  16.     constructor Init(FN : String);
  17.     destructor  Done;
  18.     procedure   WriteMode(Topic: DataStr);
  19.     procedure   Flush;
  20.     procedure   ReadMode(Topic: DataStr);
  21.     procedure   Write(S: DataStr);
  22.     function    Read: DataStr;
  23.     procedure   Delete(Topic: DataStr);
  24.     function    IsTopicExist(Topic: DataStr): Boolean;
  25.     function    GenerateNewTopic: DataStr;
  26.     function    CountTopics : LongInt;
  27.   private
  28.     ReserveStr : DataStr;
  29.   end;
  30.  
  31. procedure CodeFile(FN: String);
  32.  
  33. const
  34.   GenTopicSize: Byte = 7;
  35.   TopicChar = '■';
  36.  
  37. implementation
  38. uses Dos;
  39.  
  40. {$I-}
  41.  
  42. const
  43.   CodeStr : DataStr =
  44.   '(c) 1996 Tigers of SoftLand. Coded by Anton Zhuchkov. All rights not reserved. AZ';
  45.  
  46. var
  47.   PC : Integer;
  48. function Code(S: DataStr): DataStr;
  49. var
  50.   I : Integer;
  51.   St : DataStr;
  52. begin
  53.   St := S;
  54.   PC := 1;
  55.   for I := 1 to Length(S) do
  56.   begin
  57.     Byte(St[I]) := Byte(St[I]) xor Byte(CodeStr[PC]);
  58.     inc(PC);
  59.     if PC > Length(CodeStr) then PC := 1;
  60.   end;
  61.   Code := St;
  62. end;
  63.  
  64. procedure CodeFile(FN: String);
  65. var
  66.   F, FTo: Text;
  67.   St    : String;
  68. begin
  69.   Assign(F, FN);
  70.   Reset(F);
  71.   if IOResult <> 0 then
  72.   begin
  73.     Writeln('■ CodeFile ■ File not found: ', FN);
  74.     Halt(10);
  75.   end;
  76.   Assign(FTo, '$CODE$.$$$');
  77.   Rewrite(FTo);
  78.   while not EOF(F) do
  79.   begin
  80.     Readln(F, St);
  81.     if St[1] <> TopicChar then Writeln(FTo, Code(St)) else Writeln(FTo, St);
  82.   end;
  83.   Close(F);
  84.   Close(FTo);
  85.   Erase(F);
  86.   Rename(FTo, FN);
  87. end;
  88.  
  89.  
  90. function ReplaceExt(FN, NewExt: String): String;
  91. var
  92.   D, N, E: String;
  93. begin
  94.   FSplit(FN, D, N, E);
  95.   ReplaceExt := D + N + NewExt;
  96. end;
  97.  
  98. function TrimStr(S: String): String;
  99. var
  100.   STmp: String;
  101.   I   : Integer;
  102. begin
  103.   STmp := S;
  104.   while STmp[Byte(STmp[0])] = ' ' do
  105.      Dec(Byte(STmp[0]));
  106.   TrimStr := STmp;
  107. end;
  108.  
  109.  
  110.  
  111. constructor TDataFile.Init(FN : String);
  112. begin
  113.   FileName := FN;
  114.   Assign(F, FileName);
  115.   Reset(F);
  116.   if IOResult <> 0 then
  117.     Rewrite(F);
  118. end;
  119.  
  120. destructor TDataFile.Done;
  121. begin
  122.   Close(F);
  123. end;
  124.  
  125.  
  126. procedure TDataFile.WriteMode(Topic: DataStr);
  127. var
  128.   St: DataStr;
  129.   Search : DataStr;
  130. begin
  131.   Assign(FTmp,ReplaceExt(FileName, '.$$$'));
  132.   Rewrite(FTmp);
  133.   Search := TopicChar+TrimStr(Topic);
  134.   if not EOF(F) then
  135.     repeat
  136.       Readln(F, St);
  137.       Writeln(FTmp, St);
  138.     until (St = Search) or EOF(F);
  139.   if EOF(F) then Writeln(FTmp, Search);
  140.   CurTopic := Topic;
  141. end;
  142.  
  143. procedure TDataFile.Flush;
  144. var
  145.   St: DataStr;
  146. begin
  147.   if not EOF(F) then
  148.   begin
  149.     repeat
  150.       Readln(F, St);
  151.     until EOF(F) or (St[1] = TopicChar);
  152.     if not EOF(F) then
  153.     begin
  154.       Writeln(FTmp, St);
  155.       repeat
  156.         Readln(F, St);
  157.         Writeln(FTmp, St);
  158.       until EOF(F);
  159.     end;
  160.   end;
  161.   Close(F);
  162.   Close(FTmp);
  163.   Erase(F);
  164.   Rename(FTmp, FileName);
  165.   Reset(F);
  166. end;
  167.  
  168. procedure TDataFile.ReadMode(Topic: DataStr);
  169. var
  170.   St: DataStr;
  171.   Search : DataStr;
  172. begin
  173.   Close(F);
  174.   Reset(F);
  175.   Search := TopicChar+TrimStr(Topic);
  176.   repeat
  177.     Readln(F, St);
  178.   until (St = Search) or EOF(F);
  179.   if EOF(F) then
  180.   begin
  181.     Writeln('■ TDataFile.Readmode ■  Topic not found: ',Topic);
  182.     Halt(10);
  183.   end;
  184.   Readln(F, ReserveStr);
  185.   if EOF(F) or (ReserveStr[1] = TopicChar) then
  186.     EndTopic := True else EndTopic := False;
  187.   CurTopic := Topic;
  188. end;
  189.  
  190. procedure TDataFile.Write(S: DataStr);
  191. begin
  192. {$IFDEF SECURE}
  193.   Writeln(FTmp, Code(S));
  194. {$ELSE}
  195.   Writeln(FTmp, S);
  196. {$ENDIF}
  197. end;
  198.  
  199. function TDataFile.Read: DataStr;
  200. begin
  201.   if EndTopic then
  202.   begin
  203.     Writeln('■ TDataFile.Read ■ Topic data overflow: ', CurTopic);
  204.     Halt(10);
  205.   end;
  206.  
  207. {$IFDEF SECURE}
  208.   Read := Code(ReserveStr);
  209. {$ELSE}
  210.   Read := ReserveStr;
  211. {$ENDIF}
  212.   if not EOF(F) then
  213.   begin
  214.     Readln(F, ReserveStr);
  215.     if (ReserveStr[1] = TopicChar) then
  216.       EndTopic := True else EndTopic := False;
  217.   end else EndTopic := True;
  218. end;
  219.  
  220. procedure TDataFile.Delete(Topic: DataStr);
  221. var
  222.   Search,
  223.   Current : DataStr;
  224.   LastOne : Boolean;
  225. begin
  226.   Assign(FTmp,ReplaceExt(FileName, '.$$$'));
  227.   Rewrite(FTmp);
  228.   Search := TopicChar+TrimStr(Topic);
  229.   Close(F);
  230.   Reset(F);
  231.   Readln(F, Current);
  232.   LastOne := False;
  233.   while (Current <> Search) and not LastOne do
  234.   begin
  235.     Writeln(FTmp, Current);
  236.     if EOF(F) then LastOne := True;
  237.     if not LastOne then Readln(F, Current);
  238.   end;
  239.  
  240.   if LastOne then
  241.   begin
  242.     Writeln('■ TDataFile.Delete ■ Topic not found: ',Topic);
  243.     Halt(100);
  244.   end;
  245.  
  246.   Readln(F, Current);
  247.   while (Current[1] <> TopicChar) and not EOF(F) do
  248.     Readln(F, Current);
  249.  
  250.   if not EOF(F) then
  251.   begin
  252.     Writeln(FTmp, Current);
  253.     while not EOF(F) do
  254.     begin
  255.       Readln(F, Current);
  256.       Writeln(FTmp, Current);
  257.     end;
  258.   end;
  259.  
  260.   Close(F);
  261.   Close(FTmp);
  262.   Erase(F);
  263.   Rename(FTmp, FileName);
  264.   Reset(F);
  265. end;
  266.  
  267. function TDataFile.IsTopicExist(Topic: DataStr): Boolean;
  268. var
  269.   Found : Boolean;
  270.   S1    : DataStr;
  271. begin
  272.   Reset(F);
  273.   Found := False;
  274.   while not EOF(F) and not Found do
  275.   begin
  276.     Readln(F, S1);
  277.     if S1[1] = TopicChar then
  278.     begin
  279.       System.Delete(S1, 1, 1);
  280.       if S1 = Topic then Found := True;
  281.     end;
  282.   end;
  283.   IsTopicExist := Found;
  284. end;
  285.  
  286. function TDataFile.GenerateNewTopic: DataStr;
  287. var
  288.   S: DataStr;
  289.   I: Byte;
  290.   Valid : Boolean;
  291. begin
  292.   S[0] := Char(GenTopicSize);
  293.   repeat
  294.     for I := 1 to GenTopicSize do
  295.       S[I] := Char(Random(25) + 65);
  296.     if IsTopicExist(S) then Valid := False else Valid := False;
  297.   until Valid;
  298.   GenerateNewTopic := S;
  299. end;
  300.  
  301. function TDataFile.CountTopics : LongInt;
  302. var
  303.   I : LongInt;
  304.   S : DataStr;
  305. begin
  306.   Reset(F);
  307.   I := 0;
  308.   while not EOF(F) do
  309.   begin
  310.     Readln(F, S);
  311.     if S[1] = TopicChar then Inc(I);
  312.   end;
  313.   CountTopics := I;
  314. end;
  315.  
  316. end.
  317.